#include <cstdio>
#include <fstream>
#include <iostream>
#include <vector>
#include "interest_swap.h"
#include "yield_curve.h"

using namespace std;

InterestSwap::InterestSwap(char* input_file)
{
    FILE* fp = fopen(input_file, "r");

    double input;
    vector<double> input_vec;

    while (fscanf(fp, "%lf", &input) != EOF)
        input_vec.push_back(input);

    fclose(fp);

    notional.push_back(input_vec[0]);

    no_periods = 2*((int) input_vec[1]);

    fixed_rate = input_vec[2];

    long_short = (int) input_vec[3];

    start_date = (int) input_vec[4];

    amortize = (int) input_vec[5];

    inception = (double) start_date/365.;

    for (int i = 0; i < no_periods; i++)
	date.push_back(0);

    for (int i = 0; i < no_periods; i++)
	floating_rate.push_back(0);

    for (int i = 0; i < no_periods; i++)
	discount_rate.push_back(0);
}

double InterestSwap::compute()
{
    date[0] = inception;
    double count = 0;
    double total_net = 0;			


    for (int i = 1; i < date.size(); i++)
	{
	date[i] = date[i-1] + .5;
//		printf("Debug... date[i] is %5.5f.\n",date[i]);
	}
    for (int i = 0; i < floating_rate.size(); i++)
	{
	floating_rate[i] = get_forward_rate(date[i]);
// The next if-statement accounts for a problem with the forward rate code where one value appears negative.
	if (floating_rate[i] < 0)
	   {	
	      floating_rate[i] = - floating_rate[i];
	   };

	}
    for (int i = 0; i < discount_rate.size(); i++)
	discount_rate[i] = get_discount_rate(date[i]+.5);

    for (int i = 1; i < no_periods; i++)
	{
      notional[i] = notional[i-1];
	}

    for (int i = 1; i < no_periods; i++)
	{
	if (i%2 == 0)
	   { 
		count = count + 1;
		notional[i] = notional[i] - (count*amortize);
	   }
      }
    for (int i = 1; i < no_periods; i++)
	{
	if (notional[i] > notional[i-1])
	   { 
		notional[i] = notional[i-1];
	   }
	if (notional[i] < 0)
	   {
		notional[i] = 0;
	   }
//		printf("Debug... notional is %5.5f.\n",notional[i]);
//	      printf("Debug... amortize is %5.5f.\n",amortize);
      }


//    printf("Debug... fixed rate is %5.5f.\n",fixed_rate);


    for (int i = 1; i < no_periods; i++)
	{
	   total_net = total_net + discount_rate[i]*fixed_rate*notional[i]*long_short - (-discount_rate[i]*floating_rate[i]*
			notional[i]*long_short);
	}
	
    ofstream swap_result("swap_result.txt");
    for (int i = 1; i < no_periods; i++)
	{
           	swap_result << "Time= " <<date[i]<< "; Fixed Rate = "<< fixed_rate<<"; Floating Rate = "<<floating_rate[i]<<
			"; Notional = "<<notional[i]<< "; Discounted Fixed Cash flow = "<<
			discount_rate[i]*fixed_rate*notional[i]*long_short<<"; Discounted Floating Cash flow = "<<
			- discount_rate[i]*floating_rate[i]*notional[i]*long_short<<"; Discounted Net is "<<
			discount_rate[i]*fixed_rate*notional[i]*long_short - (-discount_rate[i]*floating_rate[i]*
			notional[i]*long_short)<<endl;
	}


    swap_result <<"Total discounted net = "<<total_net<< endl;
    swap_result <<endl;	  
    swap_result <<"*Time is numerically denominated such that '1' means 1 year from today."<< endl;	

    return 0;
}

double InterestSwap::get_forward_rate(double date)
{
 //   YieldCurve yc("input.txt");
	YieldCurve yc;
	yc.ReadSwapFile("input.txt");

    return yc.ForwardRate(date, date+.5);
}

double InterestSwap::get_discount_rate(double factor)
{
 //   YieldCurve yc("input.txt");
	YieldCurve yc;
	yc.ReadSwapFile("input.txt");

    return yc.DiscountFactor(factor);
}

void InterestSwap::print_debug()
{
    cout << "this is test of compute(): " << compute() << endl;
}
/*
InterestSwap::~InterestSwap()
{
	delete [] date;
	delete [] floating_rate;
	delete [] discount_rate;
	delete [] net_cash_flow;
	delete [] notional;

}*/

